package com.sinopec.yelofixedreader.uhf

import androidx.lifecycle.*
import com.sinopec.basemodule.lifecycle.onState
import com.sinopec.ch34x.device.core.instruct.Instruct
import com.sinopec.ch34x.device.core.instruct.InstructAble
import com.sinopec.ch34x.device.lifecycle.CreateInstruct
import kotlinx.coroutines.*
import kotlin.coroutines.EmptyCoroutineContext

/**
 * lwj at 2023/6/1
 * 自动关灯
 */
val Lifecycle.autoCloseLight: CreateInstruct
    get() {
        val ins = CreateInstruct()
        val insLight by ins
        coroutineScope.launchWhenCreated {
            insLight?.close()
        }
        onState(
            Lifecycle.Event.ON_DESTROY to {
                coroutineScope.launch {
                    insLight?.close()
                }
            })
        return ins
    }

val LifecycleOwner.autoCloseLight: CreateInstruct
    get() {
        return lifecycle.autoCloseLight
    }

suspend fun InstructAble.close() {
    write(Instruct.Global.Close)
}

/**
 * lwj at 2023/6/2
 * 关闭之前的再打开新的
 */
suspend fun InstructAble.safeWrite(instruct: Instruct) {
    close()
    write(instruct)
}

/**
 * lwj at 2023/6/5
 * 持续 时间后关闭灯
 */
suspend fun InstructAble?.timeWrite(
    instruct: Instruct,
    time: Long = 0L
): Job {
    this@timeWrite?.safeWrite(instruct)
    return withContext(currentCoroutineContext()) {
        launch {
            if (time != 0L) {
                delay(time)
                this@timeWrite?.close()
            }
        }
    }
}

/**
 * lwj at 2023/6/5
 * 在 delay 毫秒后切换到下个灯状态
 */
suspend fun InstructAble?.switchAfterDelay(
    instruct: Instruct,
    delay: Long,
    nextInstruct: Instruct,
): Job {
    return withContext(currentCoroutineContext()) {
        launch {
            //读码暂停，自动显示对应报错弹窗，提示报错音5秒，亮红灯，直到报错弹窗关闭
            this@switchAfterDelay?.safeWrite(instruct)
            delay(delay)
            this@switchAfterDelay?.safeWrite(nextInstruct)
        }
    }
}

/**
 * 订单结束
 */
suspend fun CoroutineScope.warnRing(
    instructAble: InstructAble?,
    times: Int = 3,
    instruct: Instruct = Instruct.YellowRing.Open,
):Job {
    return CoroutineScope(EmptyCoroutineContext).launch {
        instructAble ?: return@launch
        repeat(times) {
            instructAble.safeWrite(instruct)
            delay(800L)
            instructAble.close()
            delay(200L)
        }
        instructAble.close()
    }
}

/**
 * 成功
 */
suspend fun CoroutineScope.success(
    instructAble: InstructAble?,
    times: Int = 6,
    instruct: Instruct = Instruct.GreenRing.Open,
):Job {
    return CoroutineScope(EmptyCoroutineContext).launch {
        instructAble ?: return@launch
        repeat(times) {
            instructAble.safeWrite(instruct)
            delay(800L)
            instructAble.close()
            delay(200L)
        }
        instructAble.close()
    }
}

/**
 * 错误提示音
 * 每次会持续半秒
 * 之后会一直响红灯
 */
suspend fun CoroutineScope.errorRing(
    instructAble: InstructAble?,
    times: Int = 100,
    instruct: Instruct = Instruct.RedRing.Open,
    instruct2: Instruct = Instruct.Red.Open,
): Job {
    return launch {
        instructAble ?: return@launch
        repeat(times) {
            instructAble.safeWrite(instruct)
            delay(45L)
            instructAble.safeWrite(instruct2)
            delay(5L)
        }
        instructAble.safeWrite(Instruct.Red.Open)
    }
}


suspend fun CoroutineScope.error(
    instructAble: InstructAble?,
    times: Int = 100,
    instruct: Instruct = Instruct.RedRing.Open,
    instruct2: Instruct = Instruct.Red.Open,
): Job {
    return launch {
        instructAble ?: return@launch
        repeat(times) {
            instructAble.safeWrite(instruct)
            delay(45L)
            instructAble.safeWrite(instruct2)
            delay(5L)
        }
        instructAble.close()
    }
}